//package com.me.transports.netty;
//
//import io.netty.buffer.ByteBuf;
//import io.netty.buffer.Unpooled;
//import io.netty.channel.ChannelFuture;
//import io.netty.channel.ChannelFutureListener;
//import io.netty.channel.ChannelHandlerContext;
//import io.netty.channel.SimpleChannelInboundHandler;
//import io.netty.handler.codec.http.*;
//import io.netty.handler.codec.http.websocketx.*;
//import io.netty.util.CharsetUtil;
//import org.slf4j.Logger;
//import org.slf4j.LoggerFactory;
//
//import java.util.Date;
//
///**
// * @author wu_hc 【whuancai@163.com】
// */
//public class NettyWSServerHandler extends SimpleChannelInboundHandler<Object> {
//    private static final Logger logger = LoggerFactory.getLogger(NettyWSServerHandler.class);
//    private WebSocketServerHandshaker handshaker;
//
//    @Override
//    public void channelActive(ChannelHandlerContext ctx) throws Exception {
//        System.out.println("客户端与服务端连接开启");
//    }
//
//    @Override
//    public void channelInactive(ChannelHandlerContext ctx) throws Exception {
//        System.out.println("客户端与服务端连接关闭");
//    }
//
//    @Override
//    public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {
//        ctx.flush();
//    }
//
//    private void handlerWebSocketFrame(ChannelHandlerContext ctx, WebSocketFrame frame) {
//        // 判断是否关闭链路的指令
//        if (frame instanceof CloseWebSocketFrame) {
//            handshaker.close(ctx.channel(), (CloseWebSocketFrame) frame.retain());
//        }
//        // 判断是否ping消息
//        if (frame instanceof PingWebSocketFrame) {
//            ctx.channel().write(new PongWebSocketFrame(frame.content().retain()));
//            return;
//        }
//        // 文本消息
//        if (frame instanceof TextWebSocketFrame) {
//            // 返回应答消息
//            String request = ((TextWebSocketFrame) frame).text();
//            System.out.println("服务端收到：" + request);
//            logger.info(String.format("%s received %s", ctx.channel(), request));
//            TextWebSocketFrame tws = new TextWebSocketFrame(new Date().toString() + "hello ccc" + "：" + request);
//            // 返回【谁发的发给谁】
//            ctx.channel().writeAndFlush(tws);
//            return;
//        }
//
//        // 二进制
//        if (frame instanceof BinaryWebSocketFrame) {
//            System.out.println("The WebSocketFrame is BinaryWebSocketFrame");
//            BinaryWebSocketFrame binaryWebSocketFrame = (BinaryWebSocketFrame) frame;
//            byte[] by = new byte[frame.content().readableBytes()];
//            binaryWebSocketFrame.content().readBytes(by);
//            ByteBuf bytebuf = Unpooled.buffer();
//            bytebuf.writeBytes(by);
//            ctx.fireChannelRead(bytebuf);
//        }
//
//    }
//
//    private void handleHttpRequest(ChannelHandlerContext ctx, FullHttpRequest req) {
//        if (!req.getDecoderResult().isSuccess() || (!"websocket".equals(req.headers().get("Upgrade")))) {
//            sendHttpResponse(ctx, req, new DefaultFullHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.BAD_REQUEST));
//            return;
//        }
//        WebSocketServerHandshakerFactory wsFactory = new WebSocketServerHandshakerFactory(getWebSocketLocation(req), null, false);
//        handshaker = wsFactory.newHandshaker(req);
//        if (handshaker == null) {
//            WebSocketServerHandshakerFactory.sendUnsupportedVersionResponse(ctx.channel());
//        } else {
//            handshaker.handshake(ctx.channel(), req);
//        }
//    }
//
//    private static void sendHttpResponse(ChannelHandlerContext ctx, FullHttpRequest req, DefaultFullHttpResponse res) {
//        // 返回应答给客户端
//        if (res.getStatus().code() != 200) {
//            ByteBuf buf = Unpooled.copiedBuffer(res.getStatus().toString(), CharsetUtil.UTF_8);
//            res.content().writeBytes(buf);
//            buf.release();
//        }
//        // 如果是非Keep-Alive，关闭连接
//        ChannelFuture f = ctx.channel().writeAndFlush(res);
//        if (!isKeepAlive(req) || res.getStatus().code() != 200) {
//            f.addListener(ChannelFutureListener.CLOSE);
//        }
//    }
//
//    private static boolean isKeepAlive(FullHttpRequest req) {
//        return true;
//    }
//
//    @Override
//    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
//        cause.printStackTrace();
//        ctx.close();
//    }
//
//    @Override
//    protected void channelRead0(ChannelHandlerContext ctx, Object msg) throws Exception {
//        if (msg instanceof FullHttpRequest) {
//            handleHttpRequest(ctx, ((FullHttpRequest) msg));
//        } else if (msg instanceof WebSocketFrame) {
//            handlerWebSocketFrame(ctx, (WebSocketFrame) msg);
//        }
//    }
//
//    private static String getWebSocketLocation(FullHttpRequest req) {
//        return "ws://" + req.headers().get(HttpHeaders.Names.HOST);
//    }
//}